package gogo

import (
	"net/http"
	"time"

	"github.com/gorilla/websocket"
)

var (
	upgrader = websocket.Upgrader{
		// 读取存储空间大小
		ReadBufferSize: 1024,
		// 写入存储空间大小
		WriteBufferSize: 1024,
		// 允许跨域
		CheckOrigin: func(r *http.Request) bool {
			return true
		},
	}
)

func wsHandler(w http.ResponseWriter, r *http.Request) {
	var (
		wsConn *websocket.Conn
		err    error
		// data []byte
		conn *ImplConnection
		data []byte
	)
	// 完成http应答，在httpheader中放下如下参数
	if wsConn, err = upgrader.Upgrade(w, r, nil); err != nil {
		return // 获取连接失败直接返回
	}

	if conn, err = InitImplConnection(wsConn); err != nil {
		goto ERR
	}

	go func() {
		var (
			err error
		)
		for {
			// 每隔一秒发送一次心跳
			if err = conn.WriteMessage([]byte("heartbeat")); err != nil {
				return
			}
			time.Sleep(1 * time.Second)
		}

	}()

	for {
		if data, err = conn.ReadMessage(); err != nil {
			goto ERR
		}

		if ProcHandle != nil {
			Log().Info(string(data[:]))

			b, err := ProcHandle(data, conn)

			if err != nil {
				Log().Error(err.Error())

			} else if b != nil {
				conn.WriteMessage(b)
				Log().Info(string(b[:]))
			}
		}
		/*if err = conn.WriteMessage(data); err != nil {
			goto ERR
		}*/
	}

ERR:
	// 关闭当前连接
	wsConn.Close()
}

// ProcHandle 开发者注册的回调函数，初始化为nil，在RunWebSocket函数中会赋值
// []byte 接收到的内容
// *ImplConnection 发送接口指针，可用此指针回复相应客户端
var ProcHandle func([]byte, *ImplConnection) ([]byte, error)

// RunWebSocket 启动websocket服务
// pattern 静态路径
// addr 绑定本地IP和端口
// handler 开发者注册的毁掉函数
func RunWebSocket(pattern string, addr string, handler func([]byte, *ImplConnection) ([]byte, error)) {
	go func() {
		ProcHandle = handler

		// 当有请求访问pattern时，执行此回调方法
		http.HandleFunc(pattern, wsHandler)
		// 监听addr
		err := http.ListenAndServe(addr, nil)
		if err != nil {
			//log.Fatal("ListenAndServe", err.Error())
			Log().Error(err.Error())
		}
	}()
}
